package com.fingard.dsp.bank.directbank.yqb01;

import java.io.File;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.codec.digest.DigestUtils;

import com.fingard.constant.Format;
import com.fingard.dsp.bank.directConfig.ActSetItem;
import com.fingard.dsp.bank.directConfig.FtpSet;
import com.fingard.dsp.bank.directbank.bankInterface.IBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.ReqBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.ReqQryBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.RetAtsBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.RetAtsQryBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.detail.RetAtsBatPayRecDetail;
import com.fingard.io.FileHelper;
import com.fingard.net.ConnState;
import com.fingard.net.FtpReceiver;
import com.fingard.net.SftpPortClient;
import com.fingard.text.StringHelper;

public class YQB01BatPayRec extends YQB01Base implements IBatPayRec {
    @Override
    public RetAtsBatPayRec d_1988_BatPay(ReqBatPayRec p_req1988) throws Exception {
        return d_BatPayRec(p_req1988);
    }

    @Override
    public RetAtsQryBatPayRec d_1998_QryBatPay(ReqQryBatPayRec p_req1998) throws Exception {
        return d_QryBatPayRec(p_req1998);
    }

    @Override
    public RetAtsBatPayRec d_9188_BatPay(ReqBatPayRec p_req9188) throws Exception {
        return d_BatPayRec(p_req9188);
    }

    @Override
    public RetAtsQryBatPayRec d_9198_QryBatPay(ReqQryBatPayRec p_req9198) throws Exception {
        return d_QryBatPayRec(p_req9198);
    }

    public RetAtsBatPayRec d_BatPayRec(ReqBatPayRec p_reqBat) throws Exception {
        RetAtsBatPayRec retAts = new RetAtsBatPayRec(p_reqBat.reqHeader);

        try {
            ActSetItem actItem = getBankConfig().getActSetItem(p_reqBat.ownAct, "bat");
            if (actItem == null || !FileHelper.existFile(actItem.ownCertFilePath) || !FileHelper.existFile(actItem.oppCertFilePath)) {
                if (actItem == null) {
                	throw new Exception("未找到商户配置信息!");
                } else {
                	throw new Exception("商户证书不存在!");
                }
            }

            StringBuilder sbFileContent = new StringBuilder();
            
            Map<String, String> signMapParams = new HashMap<String, String>();
            
            sbFileContent.append(actItem.merchantId).append("|");
            sbFileContent.append(p_reqBat.reqBatchNO).append("|");
            sbFileContent.append("1|");
            String busiType = "";
            if ("1988".equals(p_reqBat.reqHeader.transType)) {
            	busiType = "FZRSBDF";
            } else {
            	busiType = "FZRSBDS";
            }
            sbFileContent.append(busiType).append("|");
            sbFileContent.append(p_reqBat.totalNum).append("|");
            String totalAmt = StringHelper.amountMultiply100(p_reqBat.totalAmt);
            sbFileContent.append(totalAmt).append("|");
            sbFileContent.append("CNY|");
            String transTime = Format.DateTime14Format.format(p_reqBat.getPayDateTime());
            sbFileContent.append(transTime).append("|");
            sbFileContent.append("SHA256withRSA|");
            
            signMapParams.put("merchantNo", actItem.merchantId);
            signMapParams.put("batchNo", p_reqBat.reqBatchNO);
            signMapParams.put("detailNo", "1");
            signMapParams.put("businessType", busiType);
            signMapParams.put("detailCounts", p_reqBat.totalNum);
            signMapParams.put("detailAmounts", totalAmt);
            signMapParams.put("currency", "CNY");
            signMapParams.put("mcTransDateTime", transTime);
            signMapParams.put("signType", "SHA256withRSA");
            
            StringBuilder sbDetailContent = new StringBuilder();
            int eachLineSeqID = 1;
            while (p_reqBat.readRecord()) {
            	sbDetailContent.append(eachLineSeqID++).append("|");
            	sbDetailContent.append("|");
            	sbDetailContent.append(p_reqBat.readedDetail.askNumber).append("|");
            	sbDetailContent.append("|");
            	sbDetailContent.append(StringHelper.amountMultiply100(p_reqBat.readedDetail.payAmount)).append("|");
            	sbDetailContent.append("CNY|");
            	
            	String oppAct = p_reqBat.readedDetail.recAct;
            	String oppName = p_reqBat.readedDetail.recName;
            	String oppBankCode = p_reqBat.readedDetail.recBankCode;
            	if ("9188".equals(p_reqBat.reqHeader.transType)) {
            		oppAct = p_reqBat.readedDetail.payAct;
            		oppName = p_reqBat.readedDetail.payName;
            		oppBankCode = p_reqBat.readedDetail.payBankCode;
            	}
            	if ("9036".equals(oppBankCode)) {
            		sbDetailContent.append("9|");
            		sbDetailContent.append(oppAct).append("|");
            		sbDetailContent.append("|");
            		sbDetailContent.append("|");
        		} else {
        			sbDetailContent.append("0|");
        			sbDetailContent.append("|");
        			sbDetailContent.append("|");
        			sbDetailContent.append(oppAct).append("|");
        		}
            	sbDetailContent.append(oppName).append("|");
            	sbDetailContent.append("|");
            	sbDetailContent.append("|");
            	sbDetailContent.append(p_reqBat.readedDetail.cnapsCode).append("|");
            	sbDetailContent.append(p_reqBat.readedDetail.cnapsName).append("|");
            	sbDetailContent.append("|");
            	sbDetailContent.append(p_reqBat.readedDetail.memo).append("|");
            	sbDetailContent.append("|");
            	sbDetailContent.append("|");
            	if ("1".equals(p_reqBat.readedDetail.isPrivate)) {
            		sbDetailContent.append("01");
            	} else {
            		sbDetailContent.append("02");
            	}
            	sbDetailContent.append("\n");
            }
            WriteBankLogLn2("文件明细内容明文:\r\n" + sbDetailContent.toString());
            
            String detailMsgDigest = DigestUtils.sha256Hex(sbDetailContent.toString().getBytes(getCharset()));
            signMapParams.put("detailDigest", detailMsgDigest);
            
            String signature = signWithRSA(actItem, mapToUrlStr(signMapParams));
            sbFileContent.append(signature).append("\n");
            sbFileContent.append(sbDetailContent);
            WriteBankLogLn2("送盘文件内容明文:\r\n" + sbFileContent.toString());
            
            String fileEncryptData = encryptByAES(actItem.saltKey, sbFileContent.toString());
            WriteBankLogLn2("送盘文件内容密文:\r\n" + fileEncryptData);
            
            FtpSet ftpSet = bankFront.getFtpSet("bat");
            String serviceCode = "B0006";
            ftpSet.upDir = ftpSet.getUpDir("batPay");
            if ("9188".equals(p_reqBat.reqHeader.transType)) {
            	serviceCode = "B0005";
            	ftpSet.upDir = ftpSet.getUpDir("batRec");
            }
            String fileName = actItem.inMerchantId + "_" + serviceCode + "_" + actItem.merchantId + "_" + p_reqBat.reqBatchNO + "_1.txt";
            String sendFilePath = getTempFileDirectory() + File.separator + fileName;
            FileHelper.writeFile(sendFilePath, fileEncryptData, getCharset());
            
            SftpPortClient sftpPortClient = new SftpPortClient(ftpSet);
            FtpReceiver ftpReceiver = sftpPortClient.uploadFile("", sendFilePath, ftpSet.upDir + "/" + fileName);
            
            retAts.respCode = "0";
            retAts.reqSeqID = p_reqBat.reqBatchNO;
            if (!ftpReceiver.isCompleted) {
                retAts.respCode = "-1";
                retAts.respInfo = ftpReceiver.connMsg;
            } else if (ConnState.FAIL.equals(ftpReceiver.connState)) {
            	retAts.respInfo = "上传失败";
            	retAts.transState = "BatchFailed";
            	retAts.payInfoCode = "E9999";
            } else {
            	retAts.respInfo = "上传成功";
            	retAts.transState = "Uploaded";
            	retAts.payInfoCode = "I4001";
            }
        } catch (Exception ex) {
        	ex.printStackTrace();
            retAts.respCode = "-1";
            retAts.respInfo = ex.getMessage();
            WriteBankLogLn(ex);
        }

        retAts.writeRetToATS();
        return retAts;
    }

    public RetAtsQryBatPayRec d_QryBatPayRec(ReqQryBatPayRec p_reqQryBat) throws Exception {
        RetAtsQryBatPayRec retAts = new RetAtsQryBatPayRec(p_reqQryBat.reqHeader);

        try {
            ActSetItem actItem = getBankConfig().getActSetItem(p_reqQryBat.ownAct, "bat");
            if (actItem == null || !FileHelper.existFile(actItem.ownCertFilePath) || !FileHelper.existFile(actItem.oppCertFilePath)) {
                if (actItem == null) {
                	throw new Exception("未找到账号'" + p_reqQryBat.ownAct + "'商户配置信息!");
                } else {
                	throw new Exception("商户'" + p_reqQryBat.ownAct + "'证书不存在!");
                }
            }

            FtpSet ftpSet = bankFront.getFtpSet("bat");
            String serviceCode = "B0006";
            ftpSet.downDir = ftpSet.getDownDir("batPay");
            if ("9188".equals(p_reqQryBat.reqHeader.transType)) {
            	serviceCode = "B0005";
            	ftpSet.downDir = ftpSet.getDownDir("batRec");
            }
            String downFileName = actItem.inMerchantId + "_" + serviceCode + "_" + actItem.merchantId + "_" + p_reqQryBat.reqBatchNO + "_1.txt.rpy";
            String localSavePath = getTempFileDirectory() + File.separator + downFileName;
            SftpPortClient sftpPortClient = new SftpPortClient(ftpSet);
            FtpReceiver ftpReceiver = sftpPortClient.downloadFile(ftpSet.downDir, downFileName, localSavePath);
            
            retAts.respCode = "0";
            retAts.reqSeqID = p_reqQryBat.reqBatchNO;
            if (!ftpReceiver.isCompleted) {
                retAts.respCode = "-1";
                retAts.respInfo = ftpReceiver.connMsg;
            } else {
            	retAts.respCode = "0";
                retAts.writeBeforeDetail();
            	
                String tmpEncryptRet = FileHelper.readFileText(localSavePath, getCharset());
                WriteBankLogLn2("银行回盘文件密文:\r\n" + tmpEncryptRet);
                String decryptContent = decryptByAES(actItem.saltKey, tmpEncryptRet);
                WriteBankLogLn2("银行回盘文件明文:\r\n" + decryptContent);
                
                String[] totalLine = decryptContent.split("\n");
                
                // 分析首行生成待验签数据
                String[] headline = totalLine[0].split("\\|");
                String tmpRespSign = headline[12];
                
                StringBuilder tmpVerifyData = new StringBuilder();
                tmpVerifyData.append("merchantNo=").append(headline[0]).append("&");
                tmpVerifyData.append("batchNo=").append(headline[1]).append("&");
                tmpVerifyData.append("detailNo=").append(headline[2]).append("&");
                tmpVerifyData.append("businessType=").append(headline[3]).append("&");
                tmpVerifyData.append("fileStatus=").append(headline[4]).append("&");
                tmpVerifyData.append("detailCounts=").append(headline[5]).append("&");
                tmpVerifyData.append("detailAmounts=").append(headline[6]).append("&");
                tmpVerifyData.append("currency=").append(headline[7]).append("&");
                tmpVerifyData.append("sussCounts=").append(headline[8]).append("&");
                tmpVerifyData.append("sussAmount=").append(headline[9]).append("&");
                tmpVerifyData.append("sussCurrency=").append(headline[10]).append("&");
                tmpVerifyData.append("signType=").append(headline[11]).append("&");
                
                String tmpRespDetail = decryptContent.substring(decryptContent.indexOf("\n")+1);
                String tmpRespDegist = DigestUtils.sha256Hex(tmpRespDetail.getBytes(getCharset()));
                tmpVerifyData.append("detailDigest=").append(tmpRespDegist);
                WriteBankLogLn2("待验签数据明文:\r\n" + tmpVerifyData.toString());
                		
                boolean verifyResult = verifyWithRSA(actItem, tmpVerifyData.toString(), tmpRespSign);
                if (verifyResult) {
                	for (String eachline : totalLine) {
                		String[] eachlineArr = eachline.split("\\|");
                		
                		RetAtsBatPayRecDetail tmpRetDetail = new RetAtsBatPayRecDetail();

                        if ("1998".equals(p_reqQryBat.reqHeader.transType)) {
                            tmpRetDetail.recAct = eachlineArr[9];
                            tmpRetDetail.recName = eachlineArr[10];
                        } else {
                            tmpRetDetail.payAct = eachlineArr[9];
                            tmpRetDetail.payName = eachlineArr[10];
                        }

                        tmpRetDetail.postScript = eachlineArr[2];
                        tmpRetDetail.payAmount = StringHelper.amountDivide100(eachlineArr[4]);
                        tmpRetDetail.memo = eachlineArr[16];
                        tmpRetDetail.result = StringHelper.joinNotEmpty("+", eachlineArr[22], eachlineArr[20]);
                        tmpRetDetail.payInfoCode = eachlineArr[20];

                        retAts.writeRetDetail(tmpRetDetail);
                	}
                } else {
                	retAts.respCode = "-1";
                	retAts.respInfo = "银行响应数据本地验签失败";
                }
            }
        } catch (Exception ex) {
        	ex.printStackTrace();
            retAts.respCode = "-1";
            retAts.respInfo = ex.getMessage();
            WriteBankLogLn(ex);
        }
        
        if (retAts.respCode.equals("-1") && StringHelper.isNullOrEmpty(retAts.reqSeqID)) {
            retAts.reqSeqID = p_reqQryBat.reqBatchNO;
        }
        if (retAts.respCode.equals("-1")) {
            retAts.writeBeforeDetail();
        }

        retAts.writeAfterDetail();
        return retAts;
    }
}
